<?php
/**
 * User: hjd-yao
 * Date: 2018/11/2
 * Time: 11:24
 */

namespace App\Models;

use App\Helpers\SelfEncrypt;
use App\Models\Manage\AdminLogsModel;
use App\Models\System\AuthModel;
use App\Models\System\MenuModel;
use App\Models\System\RoleModel;
use Illuminate\Support\Facades\DB;

class ManageAdminModel extends BaseModel
{
    use AdminLoginLimit;
    const ADMIN_SESSION_KEY = 'admin_auth';
    const ADMIN_CACHE_KEY = '';

    protected $table = 'manage_admins';

    public $timestamps = false;
    protected $dateFormat = 'U';

    public function getMgrNameAttribute($value)
    {
        return SelfEncrypt::decrypt($value);
    }


    /**
     * @title 判断是否为超级管理员
     * @param $mgr_id
     * @return bool
     */
    public function isSuperAdmin($mgr_id)
    {
        $info = $this->getInfo($mgr_id,['mgr_name','is_super']);
        return $info->is_super==1?true:false;
    }

    public function isLogin()
    {
        if(request()->session()->has(self::ADMIN_SESSION_KEY)){
            $admin_auth = request()->session()->get(self::ADMIN_SESSION_KEY);
            if($admin_auth['lg_info_sign'] == SelfEncrypt::dataAuthSign($admin_auth['lg_info'])){
                return true;
            }
        }
        return false;
    }

    public function getLoginId()
    {
        $info = $this->getLoginInfo();
        return $info['mgr_id'];
    }


    /**
     * @title 获取登录会员信息
     * @param string|null $field
     * @return bool
     */
    public function getLoginInfo(string $field = null)
    {
        $admin_auth = request()->session()->get(self::ADMIN_SESSION_KEY);
        $info = $admin_auth['lg_info'];
        if(!$field){
            return $info;
        }

        if(isset($info[$field])){
            return $info[$field];
        }
        return false;
    }

    public function getLoginAuth()
    {
        $admin_auth = request()->session()->get(self::ADMIN_SESSION_KEY);
        return $admin_auth['my_actions'];
    }

    public function getLoginMenu()
    {
        $admin_auth = request()->session()->get(self::ADMIN_SESSION_KEY);
        return $admin_auth['my_menu'];
    }

    /**
     * @titel 获取登录会员默认跳转页面
     * @return mixed
     */
    public function getJumpUrl()
    {
        $my_actions = $this->getLoginAuth();
        if($my_actions=='all'){
            return 'b_Index_index';
        }
        return AuthModel::whereIn('action',$my_actions)->where('auth_type',1)->value('action');
    }

    public function login($admin_name,$login_pwd)
    {
        if(!$this->loginLimit($admin_name)){
            return false;
        }
        $admin_info = self::where('mgr_name',SelfEncrypt::encrypt($admin_name))
                            ->select(['mgr_id','mgr_name','login_cipher','login_code','login_count','is_lock','is_enable','is_super','my_roles'])
                            ->first();

        if($admin_info&&$admin_info->is_lock){
            $this->errorMsg = '账号被锁定,请联系技术人员解锁';
            return false;
        }

        if(!$admin_info||$admin_info->is_enable<=0){
            $err_count = $this->errorCountLimit($admin_name);
            $this->errorMsg = '账号或密码错误,已错误'.$err_count.'次';
            return false;
        }

        if(!$this->checkLoginPwd($login_pwd,$admin_info->mgr_id)){
            $err_count = $this->errorCountLimit($admin_name);
            $this->errorMsg = '账号或密码错误,已错误'.$err_count.'次';
            return false;
        }
        $this->clearLoginLimit($admin_info->mgr_name);

        if($admin_info['is_super']!=1){
            $my_action = $this->myAuth($admin_info['my_roles']);
        }else{
            $my_action = 'all';
        }

        if(!$my_action){
            $this->errorMsg = '无权访问该网站';
            return false;
        }

        $this->autoLogin([
            'mgr_id'=>$admin_info->mgr_id,
            'mgr_name'=>$admin_info->mgr_name,
            'login_count'=>$admin_info->login_count,
            'my_actions'=>$my_action,
        ]);
        return true;
    }

    public function autoLogin($admin_info)
    {
        $auth = $update_data = [
            'login_at'=>request()->server('REQUEST_TIME'),
            'login_ip'=>get_client_ip(1),
            'login_count'=>DB::raw('`login_count`+1'),
            'mgr_token'=>SelfEncrypt::createToken(24,$admin_info['mgr_name'])
        ];
        self::where('mgr_id', $admin_info['mgr_id'])->update($update_data);
        $auth['mgr_id'] = $admin_info['mgr_id'];
        $auth['mgr_name'] = $admin_info['mgr_name'];
        $auth['login_count'] = $admin_info['login_count']+1;

        $admin_session['lg_info'] = $auth;
        $admin_session['my_actions'] = $admin_info['my_actions'];
        $admin_session['my_menu'] = $this->myMenu($admin_info['my_actions']);
        $admin_session['lg_info_sign'] = SelfEncrypt::dataAuthSign($auth);
        request()->session()->put(self::ADMIN_SESSION_KEY,$admin_session);
        cache()->forever('backend_'.$admin_info['mgr_name'],$auth['mgr_token']);
        AdminLogsModel::recordLoginLog($admin_info);
        return true;
    }

    /**
     * @title 我的权限
     * @param $my_roles
     * @return bool
     */
    public function myAuth($my_roles)
    {
        return RoleModel::init()->myAuth(str2arr($my_roles));
    }

    /**
     * @title 我的所有操作
     */
    public function myActions()
    {
        $actions = request()->session()->get(self::ADMIN_SESSION_KEY.'.all_actions');
        if(!$actions){
            $auth_model = AuthModel::where('status',1)->whereIn('auth_type',[1,2]);
            $auth = $this->getLoginAuth();
            if($auth != 'all'){
                $auth_model = $auth_model->whereIn('action',$auth);
            }
            $action = $auth_model->select(['id','title','action','parent_id'])
                ->orderBy('sort')->get()->toArray();
            $actions = list_to_tree($action,true,'id','parent_id');
            request()->session()->put(self::ADMIN_SESSION_KEY.'.all_actions',$actions);
        }
        return $actions;
    }

    /**
     * @title 我的菜单
     * @param $mgr_actions
     * @return array
     */
    public function myMenu($mgr_actions)
    {
        $menu_model = MenuModel::where('status',1);
        if($mgr_actions != 'all'){
            $menu_model = $menu_model->whereIn('url',$mgr_actions);
        }
        $menu = $menu_model->select(['id','title','url','parent_id','parent_ids','icon'])
                ->orderBy('sort')->get()->toArray();

        return list_to_tree($menu,true,'id','parent_id');
    }

    /**
     * @title 退出登录
     * @throws \Exception
     */
    public function logout()
    {
        $mgr_name = $this->getLoginInfo('mgr_name');
        cache()->forget('backend_'.$mgr_name);
        return request()->session()->forget(self::ADMIN_SESSION_KEY);
    }

    /**
     * @title 检测登录密码
     * @param $login_pwd
     * @param $mgr_id
     * @return bool
     */
    public function checkLoginPwd($login_pwd,$mgr_id)
    {
        $info = $this->getInfo($mgr_id,['mgr_id','login_cipher','login_code']);
        if(!$info){
            return false;
        }
        $str = $login_pwd.$info->login_code;
        if(!SelfEncrypt::check($str,$info->login_cipher)){
            return false;
        }
        return true;
    }

    /**
     * @title 检测安全密码
     * @param $safe_pwd
     * @param $mgr_id
     * @return bool
     */
    public function checkSafePwd($safe_pwd,$mgr_id)
    {
        $info = $this->getInfo($mgr_id,['mgr_id','safe_cipher','safe_code']);
        if(!$info){
            return false;
        }
        $str = $safe_pwd.$info->safe_code;
        if(!SelfEncrypt::check($str,$info->safe_cipher)){
            return false;
        }
        return true;
    }

    public function encryptPwd($str,$salt)
    {
        return SelfEncrypt::make($str.$salt);
    }

    public function getInfo($mgr_id='',$field = ['*'])
    {
        if(!$mgr_id){
            $mgr_id = $this->getLoginId();
        }
        $info = self::where('mgr_id',$mgr_id)->select($field)->first();
        if(!$info){
            return false;
        }
        return $info;
    }

    public function getParentIds($mgr_id=0)
    {
        $info = $this->getInfo($mgr_id,['parent_ids']);

        if (!$info||!$info->parent_ids){
            return [];
        }else{
            return array_filter(explode(',',$info->parent_ids));
        }
    }

    public function getChildren($mgr_id=0)
    {
        if(!$mgr_id){
            if(request()->session()->has(self::ADMIN_SESSION_KEY.'.my_team')){
                return request()->session()->get(self::ADMIN_SESSION_KEY.'.my_team');
            }
            $mgr_id = $this->getLoginId();
            $children = $this->whereRaw("FIND_IN_SET(?,`parent_ids`)",[$mgr_id])
                ->orWhere('mgr_id',$mgr_id)->pluck('mgr_id')->toArray();
            if (!$children){
                return [];
            }
            request()->session()->put(self::ADMIN_SESSION_KEY.'.my_team',$children);
            return $children;
        }
        return $this->whereRaw("FIND_IN_SET(?,`parent_ids`)",[$mgr_id])
            ->orWhere('mgr_id',$mgr_id)->pluck('mgr_id')->toArray();
    }

    /**
     * @title 注册管理员
     * @param $params
     * @return bool
     */
    public function addAdmin($params)
    {
        $safe_code = SelfEncrypt::createSalt(8);
        $login_code = SelfEncrypt::createSalt(8);
        $parent_id = $this->getLoginId();
        $parent_ids = $this->getParentIds($parent_id);
        $parent_ids[] = $parent_id;

        $parent_ids_str = implode(',',$parent_ids);
        if($parent_ids_str){
            $parent_ids_str = ','.$parent_ids_str.',';
        }
        $data['mgr_name'] = SelfEncrypt::encrypt($params['admin_name']);
        $data['mgr_email'] = $params['admin_email'];
        $data['mgr_mobile'] = $params['admin_mobile'];
        $data['login_cipher'] = $this->encryptPwd($params['login_pwd'],$login_code);
        $data['login_code'] = $login_code;
        $data['safe_cipher'] = $this->encryptPwd($params['safe_pwd'],$safe_code);
        $data['safe_code'] = $safe_code;
        $data['parent_id'] = $parent_id;
        $data['parent_ids'] = $parent_ids_str;
        $data['my_roles'] = isset($params['my_roles'])?arr2str($params['my_roles']):'';
        $data['created_at'] = time();
        $data['mgr_token'] = SelfEncrypt::randStr(24);
        $data['created_ip'] = get_client_ip(1);
        if(self::insert($data)){
            return true;
        }
        return false;
    }

    /**
     * @title 编辑管理员
     * @param $params
     * @param $admin_name
     * @return bool
     */
    public function editAdmin($params,$admin_name)
    {
        $data = [];
        if(isset($params['admin_name'])&&$params['admin_name']){
            $data['mgr_name'] = SelfEncrypt::encrypt($params['admin_name']);
        }
        if(isset($params['admin_email'])&&$params['admin_email']){
            $data['mgr_email'] = $params['admin_email'];
        }
        if(isset($params['admin_mobile'])&&$params['admin_mobile']){
            $data['mgr_mobile'] = $params['admin_mobile'];
        }
        if(!$data){
            $this->errorMsg='请输入要修改的信息';
            return false;
        }
        $data['updated_at'] = time();
        $data['updated_ip'] = get_client_ip(1);
        if(self::where('mgr_name',SelfEncrypt::encrypt($admin_name))->update($data)){
            return true;
        }
        $this->errorMsg='修改失败';
        return false;
    }

    public function deleteAdmin($mgr_id)
    {
        $info = $this->getInfo($mgr_id);
        $login_id = $this->getLoginId();
        if(!$info||$info->parent_id<=0||$login_id == $mgr_id ){
            $this->errorMsg = '当前账号不允许删除';
            return false;
        }
        if(self::where('mgr_id',$info->mgr_id)->delete()){
            self::where('parent_id',$mgr_id)->update(['parent_id'=>$info->parent_id]);
            $parent_ids = $info->parent_ids;
            if(!$parent_ids){
                $my_children_parent_ids = ','.$mgr_id.',';
            }else{
                $my_children_parent_ids = $parent_ids.$mgr_id.',';
            }
            $data['parent_ids'] = DB::raw('REPLACE(`parent_ids`,"'.$my_children_parent_ids.'","'.$parent_ids.'")');
            self::whereRaw("FIND_IN_SET(?,`parent_ids`)",[$mgr_id])->update($data);
            return true;
        }
        return false;
    }

    public function changeStatus($name,$status)
    {
        $data['is_enable'] = $status;
        $data['updated_at'] = time();
        $data['updated_ip'] = get_client_ip(1);
        if(self::where('mgr_name',SelfEncrypt::encrypt($name))->update($data)){
            return true;
        }
        return false;
    }

    public function updateLoginPwd($pwd,$mgr_id)
    {
        if(!$pwd){
            $this->errorMsg = '新密码不能为空';
            return false;
        }
        $login_code = SelfEncrypt::createSalt(8);
        $data['login_cipher'] = $this->encryptPwd($pwd,$login_code);
        $data['login_code'] = $login_code;
        $data['updated_at'] = time();
        $data['updated_ip'] = get_client_ip(1);
        if(self::where('mgr_id',$mgr_id)->update($data)){
            if($mgr_id == $this->getLoginId()){
                $this->logout();
            }
            return true;
        }
        return false;
    }

    public function updateSafePwd($pwd,$mgr_id)
    {
        if(!$pwd){
            $this->errorMsg = '新密码不能为空';
            return false;
        }
        $login_code = SelfEncrypt::createSalt(8);
        $data['safe_cipher'] = $this->encryptPwd($pwd,$login_code);
        $data['safe_code'] = $login_code;
        $data['updated_at'] = time();
        $data['updated_ip'] = get_client_ip(1);
        if(self::where('mgr_id',$mgr_id)->update($data)){
            return true;
        }
        return false;
    }

}